package com.yf.exam.modules.trainingarchives.pdfexport.controller;

import cn.hutool.core.thread.ThreadUtil;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.deepoove.poi.XWPFTemplate;
import com.deepoove.poi.config.Configure;
import com.deepoove.poi.data.Pictures;
import com.deepoove.poi.plugin.table.LoopRowTableRenderPolicy;
import com.yf.exam.ability.upload.dto.UploadRespDTO;
import com.yf.exam.ability.upload.service.impl.UploadServiceImpl;
import com.yf.exam.ability.upload.utils.FileUtils;
import com.yf.exam.common.entity.Result;
import com.yf.exam.common.enums.DeleteCodeEnum;
import com.yf.exam.common.enums.FileTypeEnum;
import com.yf.exam.core.api.dto.BaseIdReqDTO;
import com.yf.exam.modules.trainingarchives.evaluation.dto.EvaluationSummaryDTO;
import com.yf.exam.modules.trainingarchives.evaluation.service.IEvaluationSummaryService;
import com.yf.exam.modules.trainingarchives.evaluation.vo.EvaluationSummaryVO;
import com.yf.exam.modules.trainingarchives.file.entity.File;
import com.yf.exam.modules.trainingarchives.file.service.IFileService;
import com.yf.exam.modules.trainingarchives.headteacherlog.service.IHeadTeacherLogService;
import com.yf.exam.modules.trainingarchives.pdfexport.dto.second.*;
import com.yf.exam.modules.trainingarchives.pdfexport.dto.second.three.HeadTeacherLogListExportDTO;
import com.yf.exam.modules.trainingarchives.pdfexport.dto.second.three.StudentInfoListExportDTO;
import com.yf.exam.modules.trainingarchives.pdfexport.dto.second.three.TrainingClassScheduleListExportDTO;
import com.yf.exam.modules.trainingarchives.studentinfo.service.IStudentInfoService;
import com.yf.exam.modules.trainingarchives.teacherattendance.service.ITeacherAttendanceService;
import com.yf.exam.modules.trainingarchives.teacherplanexecution.service.ITeachingPlanExecutionService;
import com.yf.exam.modules.trainingarchives.trainingassessmentreport.service.ITrainingAssessmentReportService;
import com.yf.exam.modules.trainingarchives.trainingclassinfo.entity.TrainingClassInfo;
import com.yf.exam.modules.trainingarchives.trainingclassinfo.service.ITrainingClassInfoService;
import com.yf.exam.modules.trainingarchives.trainingclassschedule.service.ITrainingClassScheduleService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.wp.usermodel.HeaderFooterType;
import org.apache.poi.xwpf.model.XWPFHeaderFooterPolicy;
import org.apache.poi.xwpf.usermodel.*;
import org.apache.xmlbeans.impl.xb.xmlschema.SpaceAttribute;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTFldChar;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTText;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.STFldCharType;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.STHdrFtr;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.io.ClassPathResource;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.security.Principal;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;

@RestController
@RequestMapping("/api/training")
@Slf4j
@Api(tags = "培训档案-导出")
public class WordController {

    @Resource
    private ITrainingClassScheduleService iTrainingClassScheduleService;

    @Resource
    private ITrainingClassInfoService iTrainingClassInfoService;

    @Resource
    private IStudentInfoService iStudentInfoService;

    @Resource
    private IHeadTeacherLogService iHeadTeacherLogService;

    @Resource
    private ITeachingPlanExecutionService iTeachingPlanExecutionService;

    @Resource
    private ITrainingAssessmentReportService iTrainingAssessmentReportService;

    @Resource
    private ITeacherAttendanceService iTeacherAttendanceService;

    @Resource
    private UploadServiceImpl uploadService;

    @Resource
    private IEvaluationSummaryService evaluationSummaryService;

    @Resource
    private IFileService fileService;

    private static final String TEMPLATE_PATH = "templates/template.docx";

    @Value("${conf.upload.dir}")
    private String dir;


    @ApiOperation(value = "导出word")
    @RequestMapping(value = "/export",method = {RequestMethod.POST})
    public Result exportWord(@RequestBody BaseIdReqDTO reqDTO, Principal principal) {
        //导出word
        TrainingClassInfo commonData = iTrainingClassInfoService.getById(reqDTO.getId());
        if (Objects.nonNull(commonData)) {
            commonData.setExportStatus("1");
            commonData.setExportTime(LocalDateTime.now());
            iTrainingClassInfoService.updateById(commonData);
            ThreadUtil.execAsync(() -> this.exportDocOrPdf(reqDTO), false);
            return Result.ok("正在导出培训档案，请稍后下载！");
        } else {
            return Result.faild("培训档案不存在");
        }
    }

    public Result exportDocOrPdf(BaseIdReqDTO reqDTO) {
        try {
            String trainingClassInfoId = reqDTO.getId();
            //获取一期一档公用数据
            TrainingClassInfo commonData = iTrainingClassInfoService.getById(trainingClassInfoId);
            // 一、初始化安全培训计划数据
            TrainingClassInfoExportDTO trainingClassInfoExportDTO = initAqpxjhbData(trainingClassInfoId);
            //初始化培训班课程安排表数据
            TrainingClassScheduleExportPdfDTO pxbkcapbData = iTrainingClassScheduleService.getPdfData(trainingClassInfoId);
            List<TrainingClassScheduleListExportDTO> trainingClassScheduleListExportDTOList = initTrainingClassScheduleListExportDTO(pxbkcapbData);

            //初始化学员基本信息汇总表数据
            StudentInfoExportDTO studentPdfData = iStudentInfoService.getStudentPdfData(trainingClassInfoId);
            DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy年MM月dd日");

            studentPdfData.setXyjbxxhzTableName(
                    commonData.getClassName() + "  " +
                            commonData.getTrainingStartDate().format(formatter) + "至" +
                            commonData.getTrainingEndDate().format(formatter)
            );
            List<StudentInfoListExportDTO> studentInfoListExportDTOList = initStudentInfoListExportDTO(studentPdfData);
            //初始化班主任工作日志表数据
            TrainingClassInfoBzrExportDTO headTeacherLogData = iHeadTeacherLogService.getHeadTeacherLogData(trainingClassInfoId);
            Object bzrgzrzjlHeadTeacherPhotoUrl = headTeacherLogData.getBzrgzrzjlHeadTeacherPhotoUrl();
            if (Objects.nonNull(bzrgzrzjlHeadTeacherPhotoUrl) && bzrgzrzjlHeadTeacherPhotoUrl.toString().contains("file")) {
                headTeacherLogData.setBzrgzrzjlHeadTeacherPhoto(Pictures.ofLocal(uploadService.getRealPath(bzrgzrzjlHeadTeacherPhotoUrl.toString())).size(60, 30).center().create());
                headTeacherLogData.setIsPicture(true);
                headTeacherLogData.setIsText(false);
            } else {
                headTeacherLogData.setIsPicture(false);
                headTeacherLogData.setIsText(true);
            }
            List<HeadTeacherLogListExportDTO> headTeacherLogListExportDTOList = initHeadTeacherLogListExportDTO(headTeacherLogData);
            //初始化教学计划执行表数据
            List<TeachingPlanExportDTO> teachingPlanExportDTOList = iTeachingPlanExecutionService.getTeachingPlanPdfData(trainingClassInfoId);
            for (int i = 0; i < teachingPlanExportDTOList.size(); i++) {
                TeachingPlanExportDTO studentInfoListExportDTO = teachingPlanExportDTOList.get(i);
                studentInfoListExportDTO.setJxjhzxbNo(String.valueOf(i + 1));
            }
            for (TeachingPlanExportDTO teachingPlanExportDTO : teachingPlanExportDTOList) {
                Object jxjhzxbTeacherSignature = teachingPlanExportDTO.getJxjhzxbTeacherSignature();
                if (Objects.nonNull(jxjhzxbTeacherSignature) && jxjhzxbTeacherSignature.toString().contains("file")) {
                    teachingPlanExportDTO.setJxjhzxbTeacherSignature(Pictures.ofLocal(uploadService.getRealPath(jxjhzxbTeacherSignature.toString())).size(60, 30).center().create());
                    teachingPlanExportDTO.setIsPicture(true);
                    teachingPlanExportDTO.setIsText(false);
                } else {
                    teachingPlanExportDTO.setIsPicture(false);
                    teachingPlanExportDTO.setIsText(true);
                }
            }
            //初始化授课教师签到数据
            List<TeacherAttendanceExportDTO> teacherAttendanceExportDTOList = iTeacherAttendanceService.getTeacherAttendancePdfData(trainingClassInfoId);
            //初始化学员考核情况表数据
            List<StudentAssessmentExportDTO> studentAssessmentExportDTO = iStudentInfoService.getStudentExamPdfData(trainingClassInfoId);
            //获取综合考评报告
            TrainingAssessmentReportExportDTO trainingAssessmentReporPdfData = iTrainingAssessmentReportService.getTrainingAssessmentReporPdfData(trainingClassInfoId);
            //获取机构调查问卷情况总结
            EvaluationSummaryDTO evaluationSummaryDTO = new EvaluationSummaryDTO();
            evaluationSummaryDTO.setTrainingClassInfoId(trainingClassInfoId);
            evaluationSummaryDTO.setType(1);
            EvaluationSummaryVO orgEvaluationSummary = evaluationSummaryService.get(evaluationSummaryDTO);
            //获取老师调查问卷
            evaluationSummaryDTO.setType(2);
            EvaluationSummaryVO teacherEvaluationSummary = evaluationSummaryService.get(evaluationSummaryDTO);

            //获取课程教程与电子讲义
            List<FileExportDTO> fileExportList0 = initFileExportDTOList(trainingClassInfoId,FileTypeEnum.FILE_TYPE_0.code);
            //获取学员考勤
            List<FileExportDTO> fileExportList1 = initFileExportDTOList(trainingClassInfoId,FileTypeEnum.FILE_TYPE_1.code);
            //获取委托协议
            List<FileExportDTO> fileExportList2 = initFileExportDTOList(trainingClassInfoId,FileTypeEnum.FILE_TYPE_2.code);



            String systemnow = LocalDateTime.now().format(formatter);

            Map<String, Object> map = new HashMap<>();
            map.put("commonData",commonData);
            map.put("systemnow", systemnow);
            map.put("examNo", studentAssessmentExportDTO.size());
            map.put("trainingClassInfoExportDTO",trainingClassInfoExportDTO);
            map.put("pxbkcapbData",pxbkcapbData);
            map.put("trainingClassScheduleListExportDTOList",trainingClassScheduleListExportDTOList);
            map.put("studentPdfData",studentPdfData);
            map.put("studentInfoListExportDTOList",studentInfoListExportDTOList);
            map.put("headTeacherLogData",headTeacherLogData);
            map.put("headTeacherLogListExportDTOList",headTeacherLogListExportDTOList);
            map.put("teachingPlanExportDTOList",teachingPlanExportDTOList);
            map.put("teacherAttendanceExportDTOList",teacherAttendanceExportDTOList);
            map.put("studentAssessmentExportDTO",studentAssessmentExportDTO);
            map.put("trainingAssessmentReporPdfData",trainingAssessmentReporPdfData);
            map.put("orgEvaluationSummary",orgEvaluationSummary);
            map.put("teacherEvaluationSummary",teacherEvaluationSummary);
            map.put("fileExportList0",fileExportList0);
            map.put("fileExportList1",fileExportList1);
            map.put("fileExportList2",fileExportList2);
            // 三、绑定插件
            Configure config = Configure.builder()
                    .bind("trainingClassScheduleListExportDTOList", new LoopRowTableRenderPolicy())
                    .bind("studentInfoListExportDTOList", new LoopRowTableRenderPolicy())
                    .bind("headTeacherLogListExportDTOList", new LoopRowTableRenderPolicy())
                    .bind("teachingPlanExportDTOList", new LoopRowTableRenderPolicy())
                    .bind("teacherAttendanceExportDTOList", new LoopRowTableRenderPolicy())
                    .bind("studentAssessmentExportDTO", new LoopRowTableRenderPolicy())
                    .build();

            try (InputStream templateStream = new ClassPathResource(TEMPLATE_PATH).getInputStream();
                 ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream()) {
                XWPFTemplate template = XWPFTemplate.compile(templateStream, config).render(map);
//                if (Objects.nonNull(template)) {
                    // 写入到byteArrayOutputStream
                template.write(byteArrayOutputStream);
//                }
                // 输出流【byteArrayOutputStream】转为输入流【ByteArrayInputStream】
                try (XWPFDocument xwpfDocument = new XWPFDocument(new ByteArrayInputStream(byteArrayOutputStream.toByteArray()))) {
                        // 输出为docx
                    String fileName = FileUtils.processPathPostfix("docx");

                    String full = dir + fileName;
                    FileUtils.checkDir(full);
                    xwpfDocument.write(Files.newOutputStream(Paths.get(full)));
                    UploadRespDTO uploadRespDTO = uploadService.generateResult(fileName);
                    log.info("全量路径:{}", uploadRespDTO.getUrl());
                    iTrainingClassInfoService.update(new LambdaUpdateWrapper<TrainingClassInfo>()
                            .eq(TrainingClassInfo::getId, trainingClassInfoId)
                            .set(TrainingClassInfo::getExportUrl, uploadRespDTO.getUrl())
                            .set(TrainingClassInfo::getExportStatus,"2"));
                    // 输出为PDF
//                    PdfConverter.getInstance().convert(xwpfDocument, Files.newOutputStream(Paths.get(dir+ FileUtils.processPathPostfix("pdf"))), PdfOptions.create());
                    return Result.ok("文档生成成功，请下载！");
                }
            }
        } catch (IOException e) {
            log.error("生成文档失败:{}", e.getMessage());
            throw new RuntimeException(e);
        }
    }

    private List<HeadTeacherLogListExportDTO> initHeadTeacherLogListExportDTO(TrainingClassInfoBzrExportDTO headTeacherLogData) {
        List<HeadTeacherLogListExportDTO> teacherLogExportDTOList = headTeacherLogData.getTeacherLogExportDTOList();
        return teacherLogExportDTOList;

    }

    private List<StudentInfoListExportDTO> initStudentInfoListExportDTO(StudentInfoExportDTO studentPdfData) {
        List<StudentInfoListExportDTO> studentInfoListExportDTOList = studentPdfData.getStudentInfoListExportDTOList();
        for (int i = 0; i < studentInfoListExportDTOList.size(); i++) {
            StudentInfoListExportDTO studentInfoListExportDTO = studentInfoListExportDTOList.get(i);
            studentInfoListExportDTO.setXyjbxxhzNo(String.valueOf(i + 1));
        }
        return studentInfoListExportDTOList;
    }

    private List<TrainingClassScheduleListExportDTO> initTrainingClassScheduleListExportDTO(TrainingClassScheduleExportPdfDTO pxbkcapbData) {
        List<TrainingClassScheduleListExportDTO> trainingClassScheduleListExportDTOList = pxbkcapbData.getTrainingClassScheduleListExportDTOList();
        // 遍历并给每个DTO设置序号
        for (int i = 0; i < trainingClassScheduleListExportDTOList.size(); i++) {
            TrainingClassScheduleListExportDTO dto = trainingClassScheduleListExportDTOList.get(i);
            dto.setPxbkcapNo(String.valueOf(i + 1));  // 序号从1开始
        }
        return trainingClassScheduleListExportDTOList;
    }


    private TrainingClassInfoExportDTO initAqpxjhbData(String trainingClassInfoId) {
        //获取安全培训计划表数据
        TrainingClassInfoExportDTO pdfData = iTrainingClassInfoService.getPdfData(trainingClassInfoId);
        Object aqpxjhAuditorSignature = pdfData.getAqpxjhAuditorSignature();
        Object aqpxjhApproverSignature = pdfData.getAqpxjhApproverSignature();
        if (Objects.nonNull(aqpxjhAuditorSignature) && aqpxjhAuditorSignature.toString().contains("file")) {
            pdfData.setAqpxjhAuditorSignature(Pictures.ofLocal(uploadService.getRealPath(aqpxjhAuditorSignature.toString())).size(60, 30).center().create());
            pdfData.setIsPicture1(true);
            pdfData.setIsText1(false);
        } else {
            pdfData.setIsPicture1(false);
            pdfData.setIsText1(true);
        }

        if (Objects.nonNull(aqpxjhApproverSignature) && aqpxjhApproverSignature.toString().contains("file")) {
            pdfData.setAqpxjhApproverSignature(Pictures.ofLocal(uploadService.getRealPath(aqpxjhApproverSignature.toString())).size(60, 30).center().create());
            pdfData.setIsPicture2(true);
            pdfData.setIsText2(false);
        } else {
            pdfData.setIsPicture2(false);
            pdfData.setIsText2(true);
        }
        return pdfData;
    }

    private List<FileExportDTO> initFileExportDTOList(String trainingClassInfoId,String type) {
        List<FileExportDTO> fileExportList = new ArrayList<>();
        List<File> fileList = fileService.list(Wrappers.<File>lambdaQuery()
                .eq(File::getTrainingClassInfoId, trainingClassInfoId)
                .eq(File::getFileType, type)
                .eq(File::getIsDeleted, DeleteCodeEnum.UN_DELETE.code));

        for (final File file : fileList) {
            FileExportDTO fileExportDTO = new FileExportDTO();
            fileExportDTO.setFileName(file.getFileName());
            fileExportDTO.setFilePath(Pictures.ofLocal(uploadService.getRealPath(file.getFileUrl())).center().create());
            fileExportList.add(fileExportDTO);
        }
        return fileExportList;
    }
}
